package com.litbw.gui;

import java.awt.Component;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SpringLayout;

import com.litbw.dbbackend.DBUserAdapter;
import com.litbw.publicobservable.BasicUIMessage;
import com.litbw.publicobservable.LoginMessage;
import com.litbw.user.DataValidator;
import com.litbw.user.InvalidDataException;
import com.litbw.user.User;
import com.litbw.user.UserRole;


/**
 * Registration for a new user on the system. Creates a panel that is a form.
 * New users must enter all the data. Validation will occur. If the data is valid,
 * a new user will be created.
 * 
 * @author Silvia Chita
 */
public class RegisterPanel extends AbstractObservablePanel {
	/**
	 * Serial ID for the class
	 */
	private static final long serialVersionUID = 1141775265526082129L;

	/**
	 * The default name to use for this panel.
	 */
	private static final String DEF_NAME = "New User";

	/**
	 * List of Strings for the labels.
	 */
	private static final String[] labels = { "First Name: ", "Last Name: ",
			"Email: ", "Password: ", "Phone Number: ", "Address: ", "City: ",
			"State: ", "Zip: " };
	
	/**
	 * List of labels as components.
	 */
	private Component[] labelComponents = new Component[labels.length];

	/**
	 * List of Text Fields as components.
	 */
	private Component[] textComponents = new Component[labels.length];
	
	/**
	 * Layout of this panel.
	 */
	private static final LayoutManager layout = new SpringLayout();

	/**
	 * Create a new instance of the register user panel.
	 */
	public RegisterPanel() {
		super();
		setLayout(layout);
		setName(DEF_NAME);
		createComponents();
		addComponents();
	}

	/**
	 * Creates all the components and populates the lists.
	 */
	private void createComponents() {
		for (int i = 0; i < labels.length; i++) {
			Component label = new JLabel(labels[i]);
			labelComponents[i] = label;
		}
		for (int i = 0; i < labels.length; i++) {
			final Component textField = new JTextField(15);
			((JTextField)textField).setEditable(true);
			textComponents[i] = textField;
		}
		
		textComponents[3] = new JPasswordField(15);
	}
	
	/**
	 * Add the form-like components of the Registration Panel
	 */
	private void addComponents() {
		// loop to add all the labels and text boxes
		for (int i = 0; i < labels.length; i++) {
			
			add(labelComponents[i]);
			add(textComponents[i]);

			// right edge of label, relative to right edge of container
			// ("centering" label)
			((SpringLayout) layout).putConstraint(SpringLayout.EAST, labelComponents[i],
					-500, SpringLayout.EAST, this);
			// top edge of label relative to top edge of container
			((SpringLayout) layout).putConstraint(SpringLayout.NORTH, labelComponents[i],
					i * 25, SpringLayout.NORTH, this);
			// top edge of text field, relative to top edge of container
			((SpringLayout) layout).putConstraint(SpringLayout.NORTH,
					textComponents[i], i * 25, SpringLayout.NORTH, this);
			// left edge of text field, relative to edge of labels.
			((SpringLayout) layout).putConstraint(SpringLayout.WEST, textComponents[i],
					20, SpringLayout.EAST, labelComponents[i]);
		}
		
		Component create = new JButton("Create User");
		add(create);
		((JButton)create).addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				try {
					register();
				} catch (InvalidDataException e) {
					e.printStackTrace();
				}
			} });

		((SpringLayout) layout).putConstraint(SpringLayout.EAST, create, -400,
				SpringLayout.EAST, this);
		((SpringLayout) layout).putConstraint(SpringLayout.NORTH, create, 275,
				SpringLayout.NORTH, this);

	}
	
	
	/**
	 * Register a new user after checking fields.
	 * @throws InvalidDataException 
	 */
	private void register() throws InvalidDataException {
		boolean createUser = true;
		for (int i = 0; i < textComponents.length; i++) {
			if (((JTextField)textComponents[i]).getText().isEmpty()) {
				JOptionPane.showMessageDialog(this, "Field " + i + " is blank. Please fully complete the form.", "Registration Error", JOptionPane.ERROR_MESSAGE);
				createUser = false;
			}
			switch (i) {
			case 0:
				if (!DataValidator.isValidFirst(((JTextField)textComponents[i]).getText())) {
					JOptionPane.showMessageDialog(this, "Invalid First Name", "Registration Error", JOptionPane.ERROR_MESSAGE);
					createUser = false;
				}
				break;
			case 1:
				if (!DataValidator.isValidLast(((JTextField)textComponents[i]).getText())) {
					JOptionPane.showMessageDialog(this, "Invalid Last Name", "Registration Error", JOptionPane.ERROR_MESSAGE);
					createUser = false;
				}
				break;
			case 2:
				if (!DataValidator.isValidEmail(((JTextField)textComponents[i]).getText())) {
					JOptionPane.showMessageDialog(this, "Invalid Email", "Registration Error", JOptionPane.ERROR_MESSAGE);
					createUser = false;
				}
				break;
			case 3:
				if (!DataValidator.isValidPassword(((JTextField)textComponents[i]).getText())) {
					JOptionPane.showMessageDialog(this, "Invalid Password", "Registration Error", JOptionPane.ERROR_MESSAGE);
					createUser = false;
				}
				break;
			case 4:
				if (!DataValidator.isValidPhone(DataValidator.formatPhone(((JTextField)textComponents[i]).getText()))) {
					JOptionPane.showMessageDialog(this, "Invalid Phone Number", "Registration Error", JOptionPane.ERROR_MESSAGE);
					createUser = false;
				}
				break;
			case 5:
				if (!DataValidator.isValidAddress(((JTextField)textComponents[i]).getText())) {
					JOptionPane.showMessageDialog(this, "Invalid Address", "Registration Error", JOptionPane.ERROR_MESSAGE);
					createUser = false;
				}
				break;
			case 6:
				if (!DataValidator.isValidCity(((JTextField)textComponents[i]).getText())) {
					JOptionPane.showMessageDialog(this, "Invalid City", "Registration Error", JOptionPane.ERROR_MESSAGE);
					createUser = false;
				}
				break;
			case 7:
				if (!DataValidator.isValidState(((JTextField)textComponents[i]).getText())) {
					JOptionPane.showMessageDialog(this, "Invalid State", "Registration Error", JOptionPane.ERROR_MESSAGE);
					createUser = false;
				}
				break;
			case 8:
				if (!DataValidator.isValidZip(((JTextField)textComponents[i]).getText())) {
					JOptionPane.showMessageDialog(this, "Invalid Zip Code", "Registration Error", JOptionPane.ERROR_MESSAGE);
					createUser = false;
				}
				break;
			}
		}
		
		if (createUser) {
			User user = new User(((JTextField)textComponents[2]).getText(), ((JTextField)textComponents[3]).getText());
			
			user.setName(((JTextField)textComponents[0]).getText().trim(), ((JTextField)textComponents[1]).getText().trim());
			user.setAddress(((JTextField)textComponents[5]).getText());
			user.setCity(((JTextField)textComponents[6]).getText());
			user.setPhone(((JTextField)textComponents[4]).getText());
			user.setState(((JTextField)textComponents[7]).getText());
			user.setZip(((JTextField)textComponents[8]).getText());
			user.setRole(UserRole.UNASSIGNED);
			
			DBUserAdapter.addNewUser(user);
			
			for (int i = 0; i < textComponents.length; i++) {
				((JTextField)textComponents[i]).setText("");
			}
		
			setChanged();
			notifyObservers(new LoginMessage(user));
			
			setChanged();
			notifyObservers(new BasicUIMessage(BasicUIMessage.UISignal.SHOW_EVENTS));
			
			
		}
	}
}
